﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace ColdStorage.DOL
{
    [Serializable]
    public class Room : ICloneable
    {

        public InternalLoad itl = new InternalLoad();
        public Product pro = new Product();
        public Floor fFloor = new Floor();
        public Result res = new Result();
        // Danh sách các tường có trong 1 phòng
        public List<Wall> listWall = new List<Wall>();
        // Danh sách Roof có trong 1 phòng
        public List<Roof> listRoof = new List<Roof>();


        #region Room attributes
        double dbroomLadingCoefficient;
        double dbroomLength;
        double dbroomWidth;
        double dbroomHeight;
        double dbroomCapacity;
        double dbroomVolume;
        int iroomType = -1;
        int iinsideStorage = -1;
        String sroomName;

        public String sRoomName
        {
            get { return sroomName; }
            set { sroomName = value; }
        }

        public double dbRoomVolume
        {
            get { return dbroomVolume; }
            set { dbroomVolume = value; }
        }
        double dbroomArea;

        public double dbRoomArea
        {
            get { return dbroomArea; }
            set { dbroomArea = value; }
        }

        public int iInsideStorage
        {
            get { return iinsideStorage; }
            set { iinsideStorage = value; }
        }

        double dbroomOutsideTemp;

        public double dbRoomOutsideTemp
        {
            get { return dbroomOutsideTemp; }
            set { dbroomOutsideTemp = value; }
        }

        public double dbRoomLadingCoefficient
        {
            get { return dbroomLadingCoefficient; }
            set { dbroomLadingCoefficient = value; }
        }
        public double dbRoomLength
        {
            get { return dbroomLength; }
            set { dbroomLength = value; }
        }

        public double dbRoomWidth
        {
            get { return dbroomWidth; }
            set { dbroomWidth = value; }
        }

        public double dbRoomHeight
        {
            get { return dbroomHeight; }
            set { dbroomHeight = value; }
        }

        public double dbRoomCapacity
        {
            get { return dbroomCapacity; }
            set { dbroomCapacity = value; }
        }
        public int iRoomType
        {
            get { return iroomType; }
            set { iroomType = value; }
        }

        #endregion
        

        //Tính thể tích kho lạnh
        public double CalculateRoomVolume()
        {
            return dbroomHeight * dbroomWidth * dbroomLength;
        }

        //Tính diện tích kho lạnh
        public double CalculateRoomArea()
        {
            return dbroomLength * dbroomWidth;
        }

        //Tính dung tích kho lạnh
        public double CalculateRoomCapacity()
        {
            return CalculateRoomVolume() * dbroomLadingCoefficient;
        }

        //tính tổng nhiệt qua kết cấu bao che Q1
        public double CalculateCladdingHeat()
        {
            double QWall = 0;
            double QRoof = 0;
            double QFloor = 0;
            double QSum;

            // Dòng nhiệt qua tường
            foreach (Wall w in listWall)
            {
                QWall += w.CalculateWallHeat(pro.dbProductStorageTemp);
            }

            res.dbSumHeatWall = Math.Round(QWall,1);

            //Dòng nhiệt qua mái
            foreach (Roof r in listRoof)
            {
                QRoof += r.CalculateRoofHeat(dbroomOutsideTemp, pro.dbProductStorageTemp);
            }
            res.dbSumHeatRoof = Math.Round(QRoof,1);

            //Dòng nhiệt qua sàn
            QFloor += fFloor.CalculateFloorHeat(pro.dbProductStorageTemp);
            res.dbSumHeatFloor = Math.Round(QFloor,1);

            //Tính tổng nhiệt của construction
            QSum = QWall + QRoof + QFloor;
            res.dbSumConstruction = Math.Round(QSum,1);
            return QSum;
        }
        // Tính dòng nhiệt do sản phẩm và bao bì tỏa ra Q2
        public double CalculateProducHeat()
        {
            double QProduct = 0;
            double QWrapping = 0;

            //Dòng nhiệt do sản phẩm tỏa ra
            QProduct += pro.CalculateProductHeat(dbroomCapacity);
            res.dbSumProduct = Math.Round(QProduct,1);

            //Dòng nhiệt do bao bì tỏa ra
            QWrapping += pro.Calculatewrappingheat();
            res.dbSumWrapping = Math.Round(QWrapping,1);

            // Tính tổng dòng nhiệt do sản phẩm tỏa ra
            res.dbSumProductHeat = Math.Round(QProduct + QWrapping,1);
            return QProduct + QWrapping;
        }

        //Tính dòng nhiệt do thông gió buồng lạnh Q3
        public double CalculateVentilateHeat()
        {
            double QVentilate = 0;

            QVentilate += itl.CalculateVentialte(dbRoomVolume);
            res.dbSumVentialte = Math.Round(QVentilate,1);

            return QVentilate;
        }

        // Tính các dòng nhiệt do vận hành Q4
        public double CalculateOperationHeat()
        {
            double QLighting = 0;
            double QPeople = 0;
            double QEngine = 0;
            double QOpenDoor = 0;

            //Dòng nhiệt do chiếu sáng
            QLighting += itl.CalculateLightingHeat(dbroomArea);
            res.dbLightHeat = Math.Round(QLighting,1);

            //Dòng nhiệt do người tỏa ra
            QPeople += itl.CalculatePeopleHeat();
            res.dbPeopleHeat = Math.Round(QPeople,1);

            //Dòng nhiệt do máy móc tỏa ra
            QEngine += itl.CalculateEngineHeat();
            res.dbEngineHeat = Math.Round(QEngine,1);

            //Dòng nhiệt do mở cửa
            QOpenDoor += itl.CalculateDoorOpening(dbroomArea);
            res.dbOpenHeat = Math.Round(QOpenDoor,1);

            // Tổng dòng nhiệt do vận hành
            res.dbSumOperateHeat = Math.Round(QLighting + QPeople + QEngine + QOpenDoor,1);
            return QLighting + QPeople + QEngine + QOpenDoor;
        }

        // Tính dòng nhiệt do sản phẩm hô hấp
        public double CalculateFruitRespiration()
        {
            double QFruitRespiration = 0;

            QFruitRespiration += itl.CalculateFruitRespiration(dbroomCapacity);
            res.dbFruitRespiration = Math.Round(QFruitRespiration,1);
            return QFruitRespiration;
        }

        public double CalculateSumColdProductivity()
        {
            double dbSumColdProductivity = CalculateCladdingHeat() + CalculateProducHeat() + CalculateVentilateHeat() + CalculateOperationHeat() + CalculateFruitRespiration();
            res.dbSumHeatFlow = Math.Round(dbSumColdProductivity,1);
            return dbSumColdProductivity;
        }

        /// <summary>
        /// method to copy Room object to a new object
        /// </summary>
        /// <returns>a new object is Room object type</returns>
        public object Clone()
        {
            object clone;
            try
            {
                using (MemoryStream stream = new MemoryStream())
                {

                    BinaryFormatter formatter = new BinaryFormatter();

                    // Serialize this object

                    formatter.Serialize(stream, this);

                    stream.Position = 0;

                    // Deserialize to another object

                    clone = formatter.Deserialize(stream);

                }
                return clone;
            }
            catch (Exception e)
            {
                return e;
            }
        }
    }
}
